
class SmsController < ApplicationController

  skip_before_filter :verify_authenticity_token, :only => [:create, :match?]
  before_filter :verify_mobile, :only => [:create]
  before_filter :verify_ttl, :only => [:create]
  before_filter :verify_pseudonym, :only => [:create], :if => :is_not_bind_third_party_account?
  before_filter :verify_captcha, :only => [:create]

  TTL_LIMIT = 60.seconds

  # Sending verification code
  def create
    sms_code = reset_sms_code
    sms_rep = SmsService.register_msg @mobile, sms_code

    if sms_rep
      result = {:limit => TTL_LIMIT}
      result.merge!(:code => sms_code) if Rails.env.development?
      render :json => result
    else
      render :json => {:error => 'to_frequently', :mobile => @mobile}, :status => :bad_request
    end
  end

  def match?
    if params[:sms_code] == Rails.cache.read(sms_code_cache_key).to_s
      render :json => {:msg => 'match'}
    else
      render :json => {:msg => 'not_match'}
    end
  end

  private
    def verify_mobile
      @mobile = params[:mobile]
      @is_bind = true if params[:bind]
      unless @mobile =~ /^1[0-9]{10}$/
        render :json => {:error => 'invalid_mobile', :mobile => @mobile}, :status => :bad_request
        false
      end
    end

    def is_not_bind_third_party_account?
      !@is_bind
    end

    def verify_ttl
      limit = get_sms_code_ttl

      if Rails.cache.read(sms_code_cache_key) && countdown > 0
        render :json => {:error => 'ttl_limit', :limit => countdown}, :status => :bad_request
        false
      end
    end

    def verify_pseudonym
      user = User.find_by_mobile @mobile
      if user && params[:uniq].to_boolean
        render :json => {:error => 'mobile_taken', :mobile => @mobile}, :status => :bad_request
        false
      end
    end

    def verify_captcha
      unless simple_captcha_valid?
        render :json => {:error => 'invalid_captcha'}, :status => :bad_request
      end
    end

    def countdown
      return 0 if get_sms_code_ttl == 0
      TTL_LIMIT - get_sms_code_ttl
    end

    def reset_sms_code
      code = generate_sms_code
      generate_sms_code_ttl
      Rails.cache.write(sms_code_cache_key, code, :expires_in => 1800.seconds)
      code
    end

    def sms_code_cache_key
      "#{@mobile}"
    end

    def sms_code_ttl_cache_key
      "sms_ttl/#{@mobile}"
    end

    def generate_sms_code
      @sms_code ||= rand(999999).to_s.rjust(6, '0')
    end

    def generate_sms_code_ttl
      Rails.cache.write(sms_code_ttl_cache_key, Time.now.to_i, :expires_in => TTL_LIMIT)
    end

    def get_sms_code_ttl
      expired = Rails.cache.read(sms_code_ttl_cache_key)
      return 0 unless expired
      (Time.now.to_i - expired.to_i) rescue 0
    end

end

